package com.linkoog.devtools.icon_viewer.converters;

import com.linkoog.devtools.icon_viewer.ImageToIconConverter;
import com.linkoog.devtools.icon_viewer.core.IconType;
import com.linkoog.devtools.icon_viewer.core.ImageWrapper;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ImageLoader;
import com.intellij.util.ui.JBImageIcon;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class ExtendedImageConverter implements ImageToIconConverter, Disposable {

    private static final List<String> extensions = new CopyOnWriteArrayList<>(Arrays.asList("bigtiff", "dcx", "icns", "ico", "jbig2", "pam", "pbm", "pcx", "pgm", "pnm", "ppm", "psd", "rgbe", "tga", "tif", "tiff", "wbmp", "xbm", "xpm"));

    private final ThreadLocal<Boolean> CONTEXT_UPDATED = ThreadLocal.withInitial(() -> false);
    private final int WIDTH = 16;
    private final int HEIGHT = 16;


    @Override
    public Collection<String> getExtensions() {
        if (!CONTEXT_UPDATED.get()) {
            Thread.currentThread().setContextClassLoader(ExtendedImageConverter.class.getClassLoader());
            ImageIO.scanForPlugins();
            final Set<String> otherSupportedExts = Stream.of(ImageIO.getReaderFormatNames()).map(String::toLowerCase).collect(Collectors.toSet());
            extensions.addAll(otherSupportedExts);
            CONTEXT_UPDATED.set(true);
        }

        return extensions;
    }

    @Override
    public IconType getIconType() {
        return IconType.EXTENDED;
    }

    @Override
    public Image loadImage(ByteArrayInputStream byteArrayInputStream, VirtualFile virtualFile) throws IOException {
        return ImageLoader.loadFromStream(byteArrayInputStream);
    }

    @Override
    public Icon convert(VirtualFile canonicalFile, String canonicalPath) throws IOException {
        try {
            ImageInputStream imageInputStream =  ImageIO.createImageInputStream(new File(canonicalPath));
            final Iterator<ImageReader> imageReaders = ImageIO.getImageReaders(imageInputStream);
            while (imageReaders.hasNext()) {
                ImageReader imageReader = imageReaders.next();
                try {
                    imageReader.setInput(imageInputStream);
                    BufferedImage bufferedImage = imageReader.read(0);
                    Image image = bufferedImage.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_SMOOTH);
                    if (image != null) return new JBImageIcon(image);
                } catch (IOException e) {
                    //LOG.warn(e.message)
                } finally {
                    imageReader.dispose();
                }
            }
        } catch (IOException e) {
            //LOG.warn(e.message)
        }
        return null;
    }

    @Override
    public String toBase64(ImageWrapper imageWrapper) {
        return null;
    }

    @Override
    public void dispose() {
        CONTEXT_UPDATED.remove();
    }
}
